/**
 * 全局错误处理工具
 */

// 错误类型枚举
export const ERROR_TYPES = {
  NETWORK: 'NETWORK_ERROR',
  API: 'API_ERROR', 
  VALIDATION: 'VALIDATION_ERROR',
  PERMISSION: 'PERMISSION_ERROR',
  UNKNOWN: 'UNKNOWN_ERROR'
}

// 错误处理类
class ErrorHandler {
  constructor() {
    this.errorLog = []
    this.maxLogSize = 100
  }

  /**
   * 处理错误
   * @param {Error} error - 错误对象
   * @param {Object} context - 错误上下文
   * @param {string} context.component - 组件名称
   * @param {string} context.method - 方法名称
   * @param {Object} context.data - 相关数据
   */
  handleError(error, context = {}) {
    const errorInfo = this.formatError(error, context)
    
    // 记录错误日志
    this.logError(errorInfo)
    
    // 根据错误类型处理
    this.processError(errorInfo)
    
    return errorInfo
  }

  /**
   * 格式化错误信息
   */
  formatError(error, context) {
    return {
      id: Date.now() + Math.random(),
      type: this.getErrorType(error),
      message: error.message || '未知错误',
      stack: error.stack,
      timestamp: new Date().toISOString(),
      context: {
        component: context.component || 'Unknown',
        method: context.method || 'Unknown',
        data: context.data || null
      },
      userAgent: navigator.userAgent,
      url: window.location.href
    }
  }

  /**
   * 获取错误类型
   */
  getErrorType(error) {
    if (error.name === 'NetworkError' || error.message.includes('网络')) {
      return ERROR_TYPES.NETWORK
    }
    if (error.name === 'ValidationError' || error.message.includes('验证')) {
      return ERROR_TYPES.VALIDATION
    }
    if (error.name === 'PermissionError' || error.message.includes('权限')) {
      return ERROR_TYPES.PERMISSION
    }
    if (error.response && error.response.status) {
      return ERROR_TYPES.API
    }
    return ERROR_TYPES.UNKNOWN
  }

  /**
   * 记录错误日志
   */
  logError(errorInfo) {
    this.errorLog.unshift(errorInfo)
    
    // 限制日志大小
    if (this.errorLog.length > this.maxLogSize) {
      this.errorLog = this.errorLog.slice(0, this.maxLogSize)
    }
    
    // 在开发环境下输出到控制台
    if (process.env.NODE_ENV === 'development') {
      console.group('🚨 Error Handler')
      console.error('错误类型:', errorInfo.type)
      console.error('错误消息:', errorInfo.message)
      console.error('错误组件:', errorInfo.context.component)
      console.error('错误方法:', errorInfo.context.method)
      console.error('错误时间:', errorInfo.timestamp)
      if (errorInfo.stack) {
        console.error('错误堆栈:', errorInfo.stack)
      }
      if (errorInfo.context.data) {
        console.error('错误数据:', errorInfo.context.data)
      }
      console.groupEnd()
    }
  }

  /**
   * 处理不同类型的错误
   */
  processError(errorInfo) {
    switch (errorInfo.type) {
      case ERROR_TYPES.NETWORK:
        this.handleNetworkError(errorInfo)
        break
      case ERROR_TYPES.API:
        this.handleApiError(errorInfo)
        break
      case ERROR_TYPES.VALIDATION:
        this.handleValidationError(errorInfo)
        break
      case ERROR_TYPES.PERMISSION:
        this.handlePermissionError(errorInfo)
        break
      default:
        this.handleUnknownError(errorInfo)
    }
  }

  /**
   * 处理网络错误
   */
  handleNetworkError(errorInfo) {
    // 可以在这里添加网络重试逻辑
    this.showErrorMessage('网络连接异常，请检查网络设置')
  }

  /**
   * 处理API错误
   */
  handleApiError(errorInfo) {
    const message = this.getApiErrorMessage(errorInfo)
    this.showErrorMessage(message)
  }

  /**
   * 处理验证错误
   */
  handleValidationError(errorInfo) {
    this.showErrorMessage(errorInfo.message)
  }

  /**
   * 处理权限错误
   */
  handlePermissionError(errorInfo) {
    this.showErrorMessage('权限不足，请检查您的账户权限')
  }

  /**
   * 处理未知错误
   */
  handleUnknownError(errorInfo) {
    this.showErrorMessage('系统异常，请稍后重试')
  }

  /**
   * 获取API错误消息
   */
  getApiErrorMessage(errorInfo) {
    const status = errorInfo.context.data?.status
    switch (status) {
      case 400:
        return '请求参数错误'
      case 401:
        return '登录已过期，请重新登录'
      case 403:
        return '权限不足'
      case 404:
        return '请求的资源不存在'
      case 500:
        return '服务器内部错误'
      default:
        return '请求失败，请稍后重试'
    }
  }

  /**
   * 显示错误消息
   */
  showErrorMessage(message) {
    // 这里可以集成 Element UI 的消息提示
    if (window.Vue && window.Vue.prototype.$message) {
      window.Vue.prototype.$message.error(message)
    } else {
      alert(message)
    }
  }

  /**
   * 获取错误日志
   */
  getErrorLog() {
    return this.errorLog
  }

  /**
   * 清空错误日志
   */
  clearErrorLog() {
    this.errorLog = []
  }

  /**
   * 导出错误日志
   */
  exportErrorLog() {
    const dataStr = JSON.stringify(this.errorLog, null, 2)
    const dataBlob = new Blob([dataStr], { type: 'application/json' })
    const url = URL.createObjectURL(dataBlob)
    const link = document.createElement('a')
    link.href = url
    link.download = `error-log-${new Date().toISOString().split('T')[0]}.json`
    link.click()
    URL.revokeObjectURL(url)
  }
}

// 创建全局实例
const errorHandler = new ErrorHandler()

// Vue 错误处理插件
export const ErrorHandlerPlugin = {
  install(Vue) {
    // 全局错误处理
    Vue.config.errorHandler = (error, vm, info) => {
      // 获取更详细的组件信息
      const componentName = vm?.$options?.name || 
                           vm?.$options?._componentTag || 
                           vm?.$vnode?.componentOptions?.tag ||
                           'Unknown Component'
      
      // 获取更详细的错误上下文
      const errorContext = {
        component: componentName,
        method: info || 'Unknown Method',
        data: vm?.$data || null,
        props: vm?.$props || null,
        route: vm?.$route?.path || null,
        timestamp: new Date().toISOString()
      }
      
      errorHandler.handleError(error, errorContext)
    }

    // 添加全局方法
    Vue.prototype.$errorHandler = errorHandler
    
    // 添加全局错误边界组件
    Vue.component('ErrorBoundary', {
      data() {
        return {
          hasError: false,
          error: null
        }
      },
      errorCaptured(error, vm, info) {
        this.hasError = true
        this.error = error
        errorHandler.handleError(error, {
          component: 'ErrorBoundary',
          method: info,
          data: vm.$data
        })
        return false
      },
      render(h) {
        if (this.hasError) {
          return h('div', {
            class: 'error-boundary',
            style: {
              padding: '20px',
              textAlign: 'center',
              color: '#f56c6c'
            }
          }, [
            h('h3', '系统异常'),
            h('p', '页面出现错误，请刷新页面重试'),
            h('button', {
              on: {
                click: () => {
                  this.hasError = false
                  this.error = null
                  window.location.reload()
                }
              },
              style: {
                padding: '8px 16px',
                backgroundColor: '#409eff',
                color: 'white',
                border: 'none',
                borderRadius: '4px',
                cursor: 'pointer'
              }
            }, '刷新页面')
          ])
        }
        return this.$slots.default
      }
    })
  }
}

export default errorHandler
